package cevent.source.cloudcenter.server.service;

import cevent.source.cloudcenter.server.domain.GuestBook;
import cevent.source.cloudcenter.server.domain.GuestBookExample;
import cevent.source.cloudcenter.server.dto.*;
import cevent.source.cloudcenter.server.enums.YesOrNoEnum;
import cevent.source.cloudcenter.server.mapper.GuestBookMapper;
import cevent.source.cloudcenter.server.util.DuplicateUtil;
import cevent.source.cloudcenter.server.util.UUID8Util;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author cevent
 * @description 留言管理表服务层
 */
@Service
public class GuestBookService {
    private static final Logger LOG = LoggerFactory.getLogger(GuestBookService.class);
    @Resource
    private GuestBookMapper guestBookMapper;
    @Resource
    private MemberService memberService;
    @Resource
    private EmployeeService employeeService;

    //1.无分页列表查询：dto获取domain参数
    public List<GuestBookDto> guestBookDtoList() {
        GuestBookExample guestBookExample = new GuestBookExample();
        GuestBookExample.Criteria criteria = guestBookExample.createCriteria();
        criteria.andParentIdEqualTo("0");
        guestBookExample.setOrderByClause("uni_id asc");
        List<GuestBook> guestBookList = guestBookMapper.selectByExampleWithBLOBs(guestBookExample);
        List<GuestBookDto> guestBookDtoList = new ArrayList<GuestBookDto>();
        for (int i = 0; i < guestBookList.size(); i++) {
            GuestBook guestBook = guestBookList.get(i);
            GuestBookDto guestBookDto = new GuestBookDto();
            //复制拷贝(source,target)
            BeanUtils.copyProperties(guestBook, guestBookDto);
            //设置hasChildren
            boolean isChild = this.isChildren(guestBookDto.getUniId(), guestBookList);
            guestBookDto.setHasChildren(isChild);

            guestBookDtoList.add(guestBookDto);
        }
        return guestBookDtoList;
    }

    /*2.分页查询：pageDto保存数据
        list数据集合：listPageData
        当前页码：currentPage
        每页行数：size
        总计函数：totalSize
        前端可返回pageDto，无需返回值
     */
    public void getGuestBookPageDtoList(PageDto pageDto) {
        //1.分页设置（前端传入当前页和每页行数params），起始页，每页行数size
        PageHelper.startPage(pageDto.getCurrentPage(), pageDto.getSize());

        GuestBookExample guestBookExample = new GuestBookExample();
        GuestBookExample.Criteria criteria = guestBookExample.createCriteria();

        guestBookExample.setOrderByClause("create_time desc");
        List<GuestBook> guestBookList = guestBookMapper.selectByExampleWithBLOBs(guestBookExample);
        //2.将mapper查询结果复制到pageInfo
        PageInfo<GuestBook> pageInfo = new PageInfo<>(guestBookList);
        //3.pageInfo计算处理处理=>后分页的总行数set到pageDto做记录
        pageDto.setTotalSize(pageInfo.getTotal());

        List<GuestBookDto> guestBookDtoList = new ArrayList<>();
        guestBookList.stream().forEach(guestBook -> {
            GuestBookDto guestBookDto = new GuestBookDto();
            BeanUtils.copyProperties(guestBook, guestBookDto);
            //设置hasChildren
            boolean isChild = this.isChildren(guestBookDto.getUniId(), guestBookList);
            guestBookDto.setHasChildren(isChild);
            if (guestBookDto.getParentId().equals("0")) {
                guestBookDtoList.add(guestBookDto);
            }
        });

        pageDto.setListPageData(guestBookDtoList);

    }

    //根据回复类型查询
    public void getGuestBookPageSelectReply(PageSelectDto pageSelectDto) {
        PageHelper.startPage(pageSelectDto.getCurrentPage(), pageSelectDto.getSize());
        GuestBookExample guestBookExample = new GuestBookExample();
        GuestBookExample.Criteria criteria = guestBookExample.createCriteria();
        criteria.andReplyEqualTo(pageSelectDto.getTypeId());
        guestBookExample.setOrderByClause("create_time desc");
        List<GuestBook> guestBookList = guestBookMapper.selectByExampleWithBLOBs(guestBookExample);
        PageInfo<GuestBook> pageInfo = new PageInfo<>(guestBookList);
        pageSelectDto.setTotalSize(pageInfo.getTotal());
        List<GuestBookDto> guestBookDtoList = new ArrayList<>();
        guestBookList.stream().forEach(guestBook -> {
            GuestBookDto guestBookDto = new GuestBookDto();
            BeanUtils.copyProperties(guestBook, guestBookDto);
            //设置hasChildren
            boolean isChild = this.isChildren(guestBookDto.getUniId(), guestBookList);
            guestBookDto.setHasChildren(isChild);

            guestBookDtoList.add(guestBookDto);
        });

        pageSelectDto.setListPageData(guestBookDtoList);
    }

    //3.新增、修改guestBook，将传入的id转为guestBook对象本身
    public void save(GuestBookDto guestBookDto) {
        GuestBook guestBook = DuplicateUtil.copy(guestBookDto, GuestBook.class);
        if(!StringUtils.isEmpty(guestBook.getReplyContent())){
            guestBook.setReply(1);
        }
        if (StringUtils.isEmpty(guestBook.getParentId())) {
            guestBook.setParentId("0");
        }
        if (StringUtils.isEmpty(guestBookDto.getUniId())) {
            this.insert(guestBook);
        } else {
            this.update(guestBook);
        }

    }

    //4.删除模块
    public void delete(String uniId) {
        GuestBookExample guestBookExample = new GuestBookExample();
        guestBookMapper.deleteByPrimaryKey(uniId);
    }

    //批量删除
    public void deleteBatch(String uniId){
        GuestBookExample guestBookExample=new GuestBookExample();
        GuestBookExample.Criteria criteria=guestBookExample.createCriteria();
        //criteria.andUniIdEqualTo(uniId);
        List<GuestBook> guestBookList=guestBookMapper.selectByExampleWithBLOBs(guestBookExample);
        guestBookList.stream().filter(guestBook -> {
            if(guestBook.getUniId().equals(uniId)){
                delete(uniId);
            }
            return guestBook.getUniId().equals(uniId);
        }).map(guestBook -> {
            delChildren(guestBook,guestBookList);
            return guestBook;
        }).collect(Collectors.toList());
    }
    private void delChildren(GuestBook guestBook,List<GuestBook> guestBookList){
        guestBookList.stream().filter(gb -> {
            if(gb.getParentId().equals(guestBook.getUniId())){
                delete(gb.getUniId());
            }
            return gb.getParentId().equals(guestBook.getUniId());
        }).map(children->{
            delChildren(children,guestBookList);
            return children;
        }).collect(Collectors.toList());
    }

    //5.向外暴露dto，不暴露实体类：插入数据
    private void insert(GuestBook guestBook) {
        guestBook.setUniId(UUID8Util.getShortUUID());
        guestBook.setReply(YesOrNoEnum.NO.getCode());
        try {
            Date now = new Date();
            String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now);
            long time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date).getTime();
            int timeInt = (int) (time / 1000);
            guestBook.setCreateTime(now);
            guestBook.setUpdateTime(now);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        guestBookMapper.insertSelective(guestBook);
    }

    //6.更新模块
    private void update(GuestBook guestBook) {
        try {
            Date now = new Date();
            String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now);
            long time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date).getTime();
            int timeInt = (int) (time / 1000);

            guestBook.setUpdateTime(now);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        guestBook.setReply(YesOrNoEnum.YES.getCode());
        guestBookMapper.updateByPrimaryKeySelective(guestBook);
    }

    //根据reply回复类型计算数量
    public GuestBookReplyDto getReplyCount() {
        GuestBookExample guestBookExample = new GuestBookExample();
        guestBookExample.setOrderByClause("reply asc");
        List<GuestBook> guestBookList = guestBookMapper.selectByExampleWithBLOBs(guestBookExample);
        GuestBookReplyDto guestBookReplyDto = new GuestBookReplyDto();
        Integer yes = 0;
        Integer no = 0;
        for (GuestBook guestBook : guestBookList) {
            if (guestBook.getReply().equals(YesOrNoEnum.NO.getCode())) {
                no++;
            } else {
                yes++;
            }
        }
        guestBookReplyDto.setReplyYes(yes);
        guestBookReplyDto.setReplyNo(no);

        return guestBookReplyDto;
    }

    //根据uniId=parentId查询留言子节点数据
    public List<GuestBookDto> getGuestBookChildList(String uniId) {
        GuestBookExample guestBookExample = new GuestBookExample();
        GuestBookExample.Criteria criteria = guestBookExample.createCriteria();
        criteria.andParentIdEqualTo(uniId);
        guestBookExample.setOrderByClause("create_time desc");
        List<GuestBook> guestBookList = guestBookMapper.selectByExampleWithBLOBs(guestBookExample);
        List<GuestBookDto> guestBookDtoList = DuplicateUtil.copyList(guestBookList, GuestBookDto.class);
        LOG.info("获取到guestBookDtoList：{}", guestBookDtoList);
        boolean flag = isChildrenDto(uniId, guestBookDtoList());
        //设置hasChildren
        for (GuestBookDto guestBookDto : guestBookDtoList) {
            boolean isChild = this.isChildrenDto(guestBookDto.getUniId(), guestBookDtoList);
            //每个dto设置是否有子节点标识
            guestBookDto.setHasChildren(isChild);
        }
        return guestBookDtoList;
    }

    //判断是否存在子节点
    private boolean isChildrenDto(String uniId, List<GuestBookDto> guestBookDtoList) {
        Integer count = 0;
        for (GuestBookDto guestBookDto : guestBookDtoList) {
            if (guestBookDto.getParentId().equals(uniId)) {
                count++;
            }
        }
        return count > 0;
    }

    private boolean isChildren(String uniId, List<GuestBook> guestBookList) {
        Integer count = 0;
        for (GuestBook guestBook : guestBookList) {
            if (guestBook.getParentId().equals(uniId)) {
                count++;
            }
        }
        return count > 0;
    }

    //分页带条件，tree结构查询
    public void guestBookPageList(PageSelectDto pageSelectDto) {
        PageHelper.startPage(pageSelectDto.getCurrentPage(), pageSelectDto.getSize());
        GuestBookExample guestBookExample = new GuestBookExample();
        GuestBookExample.Criteria criteria = guestBookExample.createCriteria();
        if (!StringUtils.isEmpty(pageSelectDto.getTypeId())) {
            criteria.andReplyEqualTo(pageSelectDto.getTypeId());
        }
        guestBookExample.setOrderByClause("create_time desc");
        List<GuestBook> guestBookList = guestBookMapper.selectByExampleWithBLOBs(guestBookExample);
        List<GuestBookDto> guestBookDtoList = DuplicateUtil.copyList(guestBookList, GuestBookDto.class);
        //存入pageInfo总条数
        PageInfo<GuestBook> guestBookPageInfo = new PageInfo<>(guestBookList);
        pageSelectDto.setTotalSize(guestBookPageInfo.getTotal());

        List<GuestBookDto> guestBookDtoChildren = guestBookDtoList.stream().filter(guestBookDto -> {
            LOG.info("返回的父dto结构：{}", guestBookDto.getParentId().equals("0"));
            //将parentId=0返回作为父结构
            return guestBookDto.getParentId().equals("0");
        }).map(guestBookDto -> {
            //递归二级children
            guestBookDto.setChildren(getGuestBookDtoChildren(guestBookDto, guestBookDtoList));
            //返回二级
            return guestBookDto;
        }).sorted((level1, level2) -> {
            return (level1.getSort() == null ? 0 : level1.getSort()) - (level2.getSort() == null ? 0 : level2.getSort());
        }).collect(Collectors.toList());
        LOG.info("返回的pageData：{}", guestBookDtoChildren);
        pageSelectDto.setListPageData(guestBookDtoChildren);
    }

    //递归查询子留言
    private List<GuestBookDto> getGuestBookDtoChildren(GuestBookDto guestBookDto, List<GuestBookDto> guestBookDtoList) {
        List<GuestBookDto> guestBookDtoChildren = guestBookDtoList.stream().filter(guestBook -> {
            return guestBook.getParentId().equals(guestBookDto.getUniId());
        }).map(guestBookChildren -> {
            guestBookChildren.setChildren(getGuestBookDtoChildren(guestBookChildren, guestBookDtoList));
            return guestBookChildren;
        }).sorted((level1, level2) -> {
            return (level1.getSort() == null ? 0 : level1.getSort()) - (level2.getSort() == null ? 0 : level2.getSort());
        }).collect(Collectors.toList());

        return guestBookDtoChildren;
    }

    //根据会员id获取留言列表
    public List<GuestBookClientDto> getGuestBookByMemberId(String memberId) {

        GuestBookExample guestBookExample = new GuestBookExample();
        GuestBookExample.Criteria criteria = guestBookExample.createCriteria();
        criteria.andMemberIdEqualTo(memberId);
        List<GuestBook> guestBookList = guestBookMapper.selectByExampleWithBLOBs(guestBookExample);
        List<GuestBookClientDto> guestBookClientDtoList = DuplicateUtil.copyList(guestBookList, GuestBookClientDto.class);
        //递归过滤
        List<GuestBookClientDto> guestBookClientDtoChildren = guestBookClientDtoList.stream().filter(guestBookClientDto -> {
            List<MemberDto> memberDtos=getMemberDto();
            List<EmployeeDto> employeeDtos=getEmployeeDto();
            for(MemberDto memberDto:memberDtos){
                if(guestBookClientDto.getMemberId().equals(memberDto.getUniId())){
                    guestBookClientDto.setMemberName(memberDto.getNickName());
                    guestBookClientDto.setMemberIcon(memberDto.getIcon());
                }
            }
            for(EmployeeDto employeeDto:employeeDtos){
                if(guestBookClientDto.getEmployeeId().equals(employeeDto.getUniId())){
                    guestBookClientDto.setEmployeeName(employeeDto.getNickName());
                    guestBookClientDto.setEmployeeIcon(employeeDto.getIcon());
                }
            }
            return guestBookClientDto.getParentId().equals("0");
        }).map(guestBookClientDto -> {
            guestBookClientDto.setChildren(guestBookDtoChildrenClient(guestBookClientDto, guestBookClientDtoList));
            List<MemberDto> memberDtos=getMemberDto();
            List<EmployeeDto> employeeDtos=getEmployeeDto();
            for(MemberDto memberDto:memberDtos){
                if(guestBookClientDto.getMemberId().equals(memberDto.getUniId())){
                    guestBookClientDto.setMemberName(memberDto.getNickName());
                    guestBookClientDto.setMemberIcon(memberDto.getIcon());
                }
            }
            for(EmployeeDto employeeDto:employeeDtos){
                if(guestBookClientDto.getEmployeeId().equals(employeeDto.getUniId())){
                    guestBookClientDto.setEmployeeName(employeeDto.getNickName());
                    guestBookClientDto.setEmployeeIcon(employeeDto.getIcon());
                }
            }
            return guestBookClientDto;
        }).sorted((level1, level2) -> {
            return (level1.getSort() == null ? 0 : level1.getSort()) - (level2.getSort() == null ? 0 : level2.getSort());
        }).collect(Collectors.toList());
        return guestBookClientDtoChildren;
    }

    private List<GuestBookClientDto> guestBookDtoChildrenClient(GuestBookClientDto guestBookDto, List<GuestBookClientDto> guestBookClientDtoList) {
        List<GuestBookClientDto> guestBookDtoChildrenList = guestBookClientDtoList.stream().filter(guestBook -> {
            return guestBook.getParentId().equals(guestBookDto.getUniId());
        }).map(guestBookClientDtoChildren -> {
            guestBookClientDtoChildren.setChildren(guestBookDtoChildrenClient(guestBookClientDtoChildren, guestBookClientDtoList));
            return guestBookClientDtoChildren;
        }).sorted((level1, level2) -> {
            return (level1.getSort() == null ? 0 : level1.getSort()) - (level2.getSort() == null ? 0 : level2.getSort());
        }).collect(Collectors.toList());
        LOG.info("递归遍历后的guestBookChildren：{}",guestBookDtoChildrenList);
        return guestBookDtoChildrenList;
    }

    //获取员工及会员姓名和头像
    private List<MemberDto> getMemberDto(){
        List<MemberDto> memberDtos=memberService.memberDtoList();
        return memberDtos;
    }
    private List<EmployeeDto> getEmployeeDto(){
        List<EmployeeDto> employeeDtos=employeeService.employeeDtoList();
        return employeeDtos;
    }
}
